#include <iostream>
using namespace std;

class Base
{
public:
    virtual void print()
    {
        cout << "Base::print()" << endl;
    }
    virtual void display()
    {
        cout << "Base::display()" << endl;
    }
    virtual void show()
    {
        cout << "Base::show()" << endl;
    }
private:
    long _base = 10;
};

class Derived
    : public Base
{
public:
    virtual void print()
    {
        cout << "Derived::print()" << endl;
    }
    virtual void display()
    {
        cout << "Derived::display()" << endl;
    }
    virtual void show()
    {
        cout << "Derived::show()" << endl;
    }
    virtual void func()
    {
        cout << "Derived::func()" << endl;
    }
private:
    long _derived = 100;
};

void test()
{
    //包含一个虚函数指针和一个long型对象
    // cout << sizeof(Base) << endl;
    //包含一个Base的基类子对象和一个long型对象
    // cout << sizeof(Derived) << endl;

    //先来验证对象的布局
    Derived d;
    long * pderived = reinterpret_cast<long *>(&d);
    cout << pderived[0] << endl;
    cout << pderived[1] << endl;
    cout << pderived[2] << endl;

    cout << endl;

    //再来验证虚函数表
    //虚函数指针是指向函数指针的指针
    //转化为long* 使编译器按照long型的指针来理解
    long * pvtable = reinterpret_cast<long *>(pderived[0]);
    cout << pvtable[0] << endl;
    cout << pvtable[1] << endl;
    cout << pvtable[2] << endl;

    cout << endl;
    //虚表的地址
    cout << pvtable<< endl;
    cout << endl;
    //把上面的地址强制转化为普通的函数纸指针调用，发现可以调用
    typedef void (*Function)();
    Function f = (Function)(pvtable[0]);
    f();
    f = (Function)(pvtable[1]);
    f();
    f = (Function)(pvtable[2]);
    f();
    f = (Function)(pvtable[3]);
    f();
}

int main()
{
    test();
    return 0;
}